package customer

import (
	"counter-help/admin/server/global"
	"counter-help/admin/server/model/common/response"
	"counter-help/admin/server/model/customer"
	customerReq "counter-help/admin/server/model/customer/request"
	customerRes "counter-help/admin/server/model/customer/response"
	"counter-help/admin/server/model/system"
	"counter-help/admin/server/utils"
	"fmt"
	"regexp"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"go.uber.org/zap"
)

type CusUserApi struct{}

// Register 用户注册
// @Tags CusUser
// @Summary 用户注册
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "注册成功"
// @Router /cusUser/register [post]
func (b *CusUserApi) Register(c *gin.Context) {
	var r customerReq.Register
	err := c.ShouldBindJSON(&r)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if global.GVA_REDIS == nil {
		response.FailWithMessage("redis未开", c)
		return
	}
	fmt.Println("Get", r.Phone)
	v, err := global.GVA_REDIS.Get(c, r.Phone).Result()
	if err != nil {
		response.FailWithMessage("Redis 中没有 其电话的 Code:: "+err.Error(), c)
		return
	}
	global.GVA_LOG.Info(r.Phone + " Code Get:: " + v)
	if r.Code != v {
		global.GVA_LOG.Error("注册失败 验证码错误")
		response.FailWithMessage("注册失败 验证码错误！", c)
		return
	}
	var role = 1
	user := &customer.CusUser{Username: r.Username, Password: r.Password, Phone: r.Phone, Role: &role}
	userReturn, err := cusUserService.Register(*user)
	if err != nil {
		global.GVA_LOG.Error("注册失败!", zap.Error(err))
		response.FailWithMessage("注册失败", c)
		return
	}
	response.OkWithDetailed(customerRes.CusUserResponse{User: userReturn}, "注册成功", c)
}

// Login 用户登录
// @Tags CusUser
// @Summary 用户登录
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=string,msg=string} "登录成功"
// @Router /cusUser/login [post]
func (b *CusUserApi) Login(c *gin.Context) {
	fmt.Println("开始登录")
	var l customerReq.Login
	// 打印l
	err := c.ShouldBindJSON(&l)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	u := &customer.CusUser{Username: l.Username, Password: l.Password}
	user, err := cusUserService.Login(u)
	if err != nil {
		global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Error(err))
		response.FailWithMessage("用户名不存在或者密码错误", c)
		return
	}
	b.TokenNext(c, *user)
	return

}

// TokenNext 登录以后签发jwt
func (b *CusUserApi) TokenNext(c *gin.Context, user customer.CusUser) {
	token, claims, err := utils.CusLoginToken(&user)
	if err != nil {
		global.GVA_LOG.Error("获取token失败!", zap.Error(err))
		response.FailWithMessage("获取token失败", c)
		return
	}
	if !global.GVA_CONFIG.System.UseMultipoint {
		utils.SetToken(c, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
		response.OkWithDetailed(customerRes.LoginResponse{
			User:      user,
			Token:     token,
			ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
		}, "登录成功", c)
		return
	}

	if jwtStr, err := jwtService.GetRedisJWT(user.Username); err == redis.Nil {
		if err := jwtService.SetRedisJWT(token, user.Username); err != nil {
			global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
			response.FailWithMessage("设置登录状态失败", c)
			return
		}
		utils.SetToken(c, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
		response.OkWithDetailed(customerRes.LoginResponse{
			User:      user,
			Token:     token,
			ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
		}, "登录成功", c)
	} else if err != nil {
		global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
		response.FailWithMessage("设置登录状态失败", c)
	} else {
		var blackJWT system.JwtBlacklist
		blackJWT.Jwt = jwtStr
		if err := jwtService.JsonInBlacklist(blackJWT); err != nil {
			response.FailWithMessage("jwt作废失败", c)
			return
		}
		if err := jwtService.SetRedisJWT(token, user.GetUsername()); err != nil {
			response.FailWithMessage("设置登录状态失败", c)
			return
		}
		utils.SetToken(c, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
		response.OkWithDetailed(customerRes.LoginResponse{
			User:      user,
			Token:     token,
			ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
		}, "登录成功", c)
	}
}

// UpdateUserInfo 更新用户个人信息
// @Tags CusUser
// @Summary 更新用户个人信息
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "更新成功"
// @Router /cusUser/updateInfo [put]
func (b *CusUserApi) UpdateUserInfo(c *gin.Context) {
	// 解析请求体中的更新信息
	var req customerReq.UpdateUserInfoRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 从 token 中解析用户 ID
	//claims, err := utils.GetClaims(c)
	//if err != nil {
	//	response.FailWithMessage("无效的 token", c)
	//	return
	//}

	userID := utils.GetUserID(c)

	// 更新用户信息
	err := cusUserService.UpdateUserInfo(userID, req)
	if err != nil {
		global.GVA_LOG.Error("更新用户信息失败!", zap.Error(err))
		response.FailWithMessage("更新用户信息失败", c)
		return
	}

	response.OkWithMessage("更新成功", c)
}

// GetUserInfo 获取用户个人信息
// @Tags CusUser
// @Summary 获取用户个人信息
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=customerRes.UserInfoResponse,msg=string} "获取成功"
// @Router /cusUser/getInfo [get]
func (b *CusUserApi) GetUserInfo(c *gin.Context) {
	// 从 token 中解析用户 ID
	// claims, err := utils.GetClaims(c)
	// if err != nil {
	//	response.FailWithMessage("无效的 token", c)
	//	return
	//}

	userID := utils.GetUserID(c)

	// 获取用户信息
	user, err := cusUserService.GetUserInfo(userID)
	if err != nil {
		global.GVA_LOG.Error("获取用户信息失败!", zap.Error(err))
		response.FailWithMessage("获取用户信息失败", c)
		return
	}

	response.OkWithDetailed(user, "获取成功", c)
}

// RegisterByPhone 网页手机号登陆
func (b *CusUserApi) RegisterByPhone(c *gin.Context) {
	response.OkWithMessage("获取成功", c)
}

func (b *CusUserApi) ChangePassword(c *gin.Context) {
	var p customerReq.ChangePass
	err := c.ShouldBindJSON(&p)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if p.OldPassword == "" {
		response.FailWithMessage("旧密码不能为空", c)
		return
	}
	if p.NewPassword == "" {
		response.FailWithMessage("新密码不能为空", c)
		return
	}
	fmt.Println("22222")
	userID := utils.GetUserID(c)
	fmt.Println("22222", userID)
	// 获取用户信息
	user, err := cusUserService.GetUserInfo(userID)
	if err != nil {
		global.GVA_LOG.Error("用户不存在!", zap.Error(err))
		response.FailWithMessage("用户不存在", c)
		return
	}
	fmt.Println("22222555", userID)
	err = cusUserService.ChangePass(userID, p.OldPassword, p.NewPassword)
	if err != nil {
		response.FailWithMessage("操作失败"+err.Error(), c)
		return
	}
	response.OkWithDetailed(user, "操作成功", c)
}

// ResetPassword 重置密码
// @Tags CusUser
// @Summary 重置密码（忘记密码）
// @accept application/json
// @Produce application/json
// @Param data body customerReq.ResetPasswordRequest true "手机号, 新密码, 验证码"
// @Success 200 {object} response.Response{msg=string} "重置成功"
// @Router /cusUser/resetPassword [post]
func (b *CusUserApi) ResetPassword(c *gin.Context) {
	var req customerReq.ResetPasswordRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 验证手机号格式
	pattern := `^1[3-9]\d{9}$`
	reg := regexp.MustCompile(pattern)
	if !reg.MatchString(req.Phone) {
		response.FailWithMessage("手机号格式不正确", c)
		return
	}

	// 验证验证码
	code, err := global.GVA_REDIS.Get(c, req.Phone).Result()
	if err != nil || code != req.Code {
		response.FailWithMessage("验证码错误或已过期", c)
		return
	}

	// 查找用户
	var user customer.CusUser
	if err := global.GVA_DB.Where("phone = ?", req.Phone).First(&user).Error; err != nil {
		response.FailWithMessage("用户不存在", c)
		return
	}

	// 加密新密码
	hashedPassword := utils.BcryptHash(req.NewPassword)

	// 更新密码
	err = global.GVA_DB.Model(&user).Update("password", hashedPassword).Error
	if err != nil {
		global.GVA_LOG.Error("更新密码失败!", zap.Error(err))
		response.FailWithMessage("更新密码失败", c)
		return
	}

	response.OkWithMessage("密码重置成功", c)
}
